package imlayer

import (
    "fmt"
    "time"
	"strconv"
	"errors"
	"encoding/json"
	"dhfshop/models/im"
	"dhfshop/models/isv"
	"dhfshop/models/org"
	"dhfshop/models/member"
	"dhfshop/service/wscom"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
)

/**************************************************************
处理逻辑:
在线查找的时候，优先查找上次聊过的客服
如果上次聊过的客服不在线，再找其他在线客服
如果没有在线客服，才会根据有效formid，找能发出去模板消息的客服
***************************************************************/

func ForwardAgentMsg(msg *im.WxMsgReceiptRecords, msgUser *org.MsgCacheUser) error {
	//收到消息的自动回复
	if cfg, err := im.GetAutoRspCfgByAppId(msg.AppId); err == nil {
		if cfg.RcvmsgReplyOpen == "1" {
			if custAccount, err := isv.GetCustAccountByAppId(msg.AppId); err == nil {
			    if cfg.RcvmsgReplyType == "image" {
					if dstMsgBody, err := getActuralMediaId(cfg.RcvmsgReplyInfo); err == nil {
						SendAppCustomerMessage(msg.AppId,custAccount.AccessToken,msg.FromUserName, cfg.RcvmsgReplyType,dstMsgBody)
					}
				}else{
					SendAppCustomerMessage(msg.AppId,custAccount.AccessToken,msg.FromUserName,cfg.RcvmsgReplyType, cfg.RcvmsgReplyInfo)   
				}
			}
		}
	}
	chatRecord := &im.ChatRecord{PartnerId:msgUser.PartnerId,AppId:msg.AppId,ChatSessionId:0,
	                             MemberOpenId:msg.FromUserName,MsgId:msg.MsgId,MsgType:msg.MsgType,MsgTime:msg.CreateTime,
								 SendBy:1,StatusId:1,MsgBody:msg.MsgBody}
	if msg.MsgType == "text" {
		body := struct {
			Content string `json:"content"` 
		}{}
		if err := json.Unmarshal([]byte(msg.MsgBody), &body); err == nil {
		    chatRecord.Content = body.Content 
		}
	}else if msg.MsgType == "image" {
		body := struct {
			MediaId string `json:"media_id"`
	        PicURL  string `json:"pic_url"`
		}{}
		if err := json.Unmarshal([]byte(msg.MsgBody), &body); err == nil {
			chatRecord.Link = body.PicURL
		    chatRecord.MediaId = body.MediaId
		}
	}else if msg.MsgType == "miniprogrampage" {
	    body := struct {
			Title        string `json:"title"`
	        PagePath     string `json:"page_path"`
		    ThumbUrl     string `json:"thumb_url"`
		    ThumbMediaId string `json:"thumb_media_id"`
		}{}
		if err := json.Unmarshal([]byte(msg.MsgBody), &body); err == nil {
			chatRecord.Content = body.Title
		    chatRecord.Link = body.PagePath
		    chatRecord.MediaId = body.ThumbMediaId
		}
	}else{
	    
	}
	im.AddChatRecord(chatRecord)
	chatSession := new(im.ChatSession)
	chatSession, err := im.GetChatSessionByMemberOpenId(msg.FromUserName)
	if err == orm.ErrNoRows {
		chatSession.PartnerId = msgUser.PartnerId
		chatSession.AppId = msg.AppId
		chatSession.MemberOpenId = msg.FromUserName
		chatSession.AgentOpenId = ""                //当前为空
		chatSession.StatusId = 0
		chatSession.AgentNewRspNum = 0
		chatSession.StartTime = msg.CreateTime
		chatSession.ExpireTime = msg.CreateTime.Add(48*time.Hour)
		chatSession.ChatSessionId, _= im.AddChatSession(chatSession)
		chatSession.IsRead = 1
	}else if err == nil {
		chatSession.StartTime = msg.CreateTime
		chatSession.ExpireTime = msg.CreateTime.Add(48*time.Hour)
		chatSession.IsRead = 1
		im.UpdateChatSessionById(chatSession, "start_time", "expire_time", "is_read")
	}else{
	
	}
	if records, err := im.GetUnreadMessage(msgUser.PartnerId); err == nil {
		if len(records) > 0 {
			latestRecord := records[0]
			msgId := strconv.FormatInt(latestRecord.ChatRecordId, 10)
			//获取一个有效的在线客服ID
			if c, err := GetWsOneOnlineAgent(chatSession.AgentOpenId, msgUser.OpenIdUserId); err == nil {
				req := im.NewRequestDao()
				req.Cmd = "receive"
				req.AppId = msg.AppId
				req.MemberOpenId = msg.FromUserName
				req.AgentOpenId = msg.ToUserName
				req.MsgId = msgId
				req.UnreadCount = len(records)
				req.CreateTime = msg.CreateTime.Unix()
				message, _ := json.Marshal(req)
				requestSrv := wscom.NewRequestSrv()
				requestSrv.ParserMsg(c, message)
			}else{
				//发送离线模板提醒，需要用后台管理的app_id,不能用商家的app_id
				beego.Debug("GetWsOneOnlineAgent:", msg.AppId, err.Error())
				if len(msgUser.OpenIdUserId) < 1 {
				    beego.Debug("no agent in system")
					return errors.New("no agent in system")
				}
				sellerAppID := beego.AppConfig.String("SellerAppID")
				if adminAuthorize, err := isv.GetAuthorizeByAppId(sellerAppID); err == nil {
					adminAccessToken := adminAuthorize.AccessToken
					miniAppTemplateId := "zRIp_qoVqtKc6h9GciGHXeUnvyOFKULEUhLg3vsuiJU"
					if formIdCache, err := im.GetValidFormId(msgUser.OpenIdUserId, "chat"); err == nil {
						beego.Debug("After GetValidFormId:", msgUser.OpenIdUserId)
						page := fmt.Sprintf("pages/admin/index/index?cmd=chat&partnerid=%d&appid=%s&openid=%s",msgUser.PartnerId,msg.AppId,msg.FromUserName)
						buyerNick := ""
						if member, err := member.GetMemberByOpenId(msg.FromUserName); err == nil {
							buyerNick = member.Name
						}
						//ToAgentTemplateMsg(adminAccessToken,page,buyerNick,formIdCache.OpenId,miniAppTemplateId,formIdCache.FormId,msg.MsgType,msg.MsgBody)
						UniformToAgentTemplateMsg("",adminAccessToken,page,buyerNick,formIdCache.OpenId,miniAppTemplateId,formIdCache.FormId,msg.MsgType,msg.MsgBody)						   
					}else{
						beego.Emergency("GetValidFormId:", msg.AppId, err.Error())
					}
				}else{
					beego.Emergency("GetAuthorizeByAppId:", msg.AppId, err.Error())
					adminAccessToken := adminAuthorize.AccessToken
					pubMpAppid := "wx204da65aa7d948b0"
					mpTemplateId := ""
					page := ""
					openId := ""
					buyerNick := ""
					if member, err := member.GetMemberByOpenId(msg.FromUserName); err == nil {
						openId = member.OpenID
						buyerNick = member.Name
					}
					UniformToAgentTemplateMsg(pubMpAppid,adminAccessToken,page,buyerNick,openId,mpTemplateId,"",msg.MsgType,msg.MsgBody)	
				}
			}	
		}
	}
	return nil
}

func GetWsOneOnlineAgent(sessionOpenId string,openIdUserId map[string]int64)(*wscom.ConnectSvr, error) {
	if len(sessionOpenId) > 0 {
	    if userId, ok := openIdUserId[sessionOpenId]; ok {
		    userIdStr := strconv.FormatInt(userId, 10)
		    token := "phone_" + userIdStr
			if c, err := wscom.ConnectHub.GetConnectSvr(token); err == nil {
			    return c, nil
			}
			token = "pc_" + userIdStr
			if c, err := wscom.ConnectHub.GetConnectSvr(token); err == nil {
			    return c, nil
			}
		}
	}
	for _, value:= range openIdUserId {
		userIdStr := strconv.FormatInt(value, 10)
		token := "phone_" + userIdStr
		if c, err := wscom.ConnectHub.GetConnectSvr(token); err == nil {
			return c, nil
		}
		token = "pc_" + userIdStr
		if c, err := wscom.ConnectHub.GetConnectSvr(token); err == nil {
			return c, nil
		}
	}
	return &wscom.ConnectSvr{}, errors.New("Error: no valid online agent")
}
